package com.atguigue.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author: Michael
 * @date: 2025/5/14
 * @desc:
 */
public class TestCar {

    @Test
    public void test1() throws Exception {
        // 1 类名.class
        Class clazz1 = Car.class;

        // 2 对象.getClass()
        Class clazz2 = new Car().getClass();

        // 3 Class.forName("全路径")
        Class clazz3 = Class.forName("com.atguigue.reflect.Car");

        Car car = (Car) clazz3.getDeclaredConstructor().newInstance();
        System.out.println(car);
    }

    @Test
    public void test2() throws Exception {
        Class clazz = Car.class;
        // 获取所有构造 public 的 构造方法
//        Constructor[] constructors = clazz.getConstructors();
        // 包含私有的方法
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + constructor.getParameterCount());
        }

        // 指定有参数构造创建对象
        Constructor c1 = clazz.getConstructor(String.class, int.class, String.class);
        Car car1 = (Car) c1.newInstance("夏利", 10, "红色");
        System.out.println(car1);
        // 获取私有的构造方法
//        clazz.getDeclaredConstructor();
    }

    @Test
    public void test3() throws Exception {
        // 获取属性
        Class clazz = Car.class;
        Car car = (Car) clazz.getDeclaredConstructor().newInstance();
        // 获取所有public属性
//        Field[] fields = clazz.getFields();
        // 获取所有属性，包含私有属性
        Field[] fields1 = clazz.getDeclaredFields();
        for (Field field : fields1) {
            if (field.getName().equals("name")){
                // 设置允许访问
                field.setAccessible(true);
                field.set(car, "五菱宏光");
            }
            System.out.println(field.getName());
            System.out.println(car);
        }
    }

    @Test
    public void test4() throws Exception {
        // 获取方法
        Car car = new Car("奔驰", 10, "黑色");
        Class clazz = car.getClass();

        // 1 public 方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if (method.getName().equals("toString")){
                String invoke = (String) method.invoke(car);
                System.out.println("toString方法执行了 ： " + invoke);
            }
        }

        // 2 private 方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
            if (declaredMethod.getName().equals("toString")){
                declaredMethod.setAccessible(true);
                String invoke = (String) declaredMethod.invoke(car);
                System.out.println("toString方法执行了2 ： " + invoke);
            }
        }
    }

}
